<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Canvas graphs</title><link rel="stylesheet" type="text/css" href="manual.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.0"><link rel="home" href="index.html" title="JpGraph Manual"><link rel="up" href="ch17.html" title="Chapter 17. Additional graph types"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Canvas graphs</th></tr><tr><td width="20%" align="left"> </td><th width="60%" align="center">Chapter 17. Additional graph types</th><td width="20%" align="right"> </td></tr></table><hr></div><div class="sect1" title="Canvas graphs"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sec.canvas-graph"></a>Canvas graphs</h2></div></div></div>
        
        <p>This is basically a free form blank canvas where any graphics can be drawn. Canvas
            graphs area also used as the basic graph for graphic tables as described in <a class="xref" href="ch19.html" title="Chapter 19. Graphical tables">Chapter 19. <i>Graphical tables</i></a></p>
        <p>The library provides two module files to aid with this
                "j<code class="filename">pgraph_canvas.php</code>" and
                "<code class="filename">jpgraph_canvtools.php</code>". The second module is strictly speaking
            not necessary but provides a number of utility classes that makes it much easier to work
            with canvas.</p>
        <p>Canvas graphs is provided as a layer to make is easier to create arbitrary images and
            still make use of some of the convenience methods available in the library (like font
            and color support). </p>
        <p>Canvas graphs makes it easy to use the low level graphic drawing primitives in the
            library provided by the two classes </p>
        <p>
            </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
                    <p><code class="code">class Image</code></p>
                    <p>This is the basic low level class that encapsulates the GD library by
                        providing a complete framework for using graphic primitives with a coherent
                        API and many convenience methods.</p>
                </li><li class="listitem">
                    <p><code class="code">class RotImage</code></p>
                    <p>This is a descendant of class Image that in addition to the basic
                        primitives also provides support for rotation of graphs</p>
                </li></ol></div><p>
        </p>
        <p>It is possible to work at different levels of abstraction when creating a
            canvas.</p>
        <p>
            </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
                    <p>By only using the basic Image and RotImage classes. This can be considered
                        one abstraction level above the most basic GD libraries</p>
                </li><li class="listitem">
                    <p>By making use of the functionality provided by <code class="code">class
                            CanvasGraph</code> and the supporting classes (e.g. <code class="code">class
                            CanvasScale</code>). By using the canvas scale class it is possible to
                        defining a coordinate grid on the canvas. These coordinates can then be used
                        instead of absolute pixels which is necessary to us ethe basic Image and
                        RotImage classes.</p>
                </li></ol></div><p>
        </p>
        <p>A concrete example of how canvas graphs can be used can be seen in <a class="xref" href="ch08s02.html#fig.listfontsex1" title="Figure 8.1. List of all latin TTF fonts. (listfontsex1.php)">Figure 8.1. List of all latin TTF fonts. <code class="uri"><a class="uri" href="example_src/listfontsex1.html" target="_top">(<code class="filename">listfontsex1.php</code>)</a></code> </a> where all the available fonts have been drawn on a
            canvas.</p>
        <div class="sect2" title="Creating a simple canvas"><div class="titlepage"><div><div><h3 class="title"><a name="id2578744"></a>Creating a simple canvas</h3></div></div></div>
            
            <p>Creating a canvas gives you the opportunity draw arbitrary shapes on a "white"
                piece of paper. Let's first show a simple example were we just draw a text box. </p>
            <p>
                </p><div class="example"><a name="example.canvasex01"></a><p class="title"><b>Example 17.1. A simple canvas graph to draw a text box (<code class="filename">canvasex01.php</code>) </b></p><div class="example-contents">  <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content=&quot;text/plain; charset=utf-8&quot;</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex01.php,v 1.3 2002/10/23 08:17:23 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">teal</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Draw a text box in the middle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$txt</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">This</span><span class="hl-special">\n</span><span class="hl-string">is</span><span class="hl-special">\n</span><span class="hl-string">a TEXT!!!</span><span class="hl-quotes">&quot;</span><span class="hl-code">;
</span><span class="hl-var">$t</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Text</span><span class="hl-brackets">(</span><span class="hl-var">$txt</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$t</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetFont</span><span class="hl-brackets">(</span><span class="hl-identifier">FF_ARIAL</span><span class="hl-code">,</span><span class="hl-identifier">FS_BOLD</span><span class="hl-code">,</span><span class="hl-number">40</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> How should the text box interpret the coordinates?</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Align</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">center</span><span class="hl-quotes">'</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">top</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> How should the paragraph be aligned?</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-&gt;</span><span class="hl-identifier">ParagraphAlign</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">center</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a box around the text, white fill, black border and gray shadow</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetBox</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">white</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">black</span><span class="hl-quotes">&quot;</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">gray</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the text</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$t</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-inlinetags">?&gt;</span></pre></td></tr></table></div></div></div><p><br class="example-break">  </p><div class="figure"><a name="fig.canvasex01"></a><p class="title"><b>Figure 17.22. A simple canvas graph to draw a text box <code class="uri"><a class="uri" href="example_src/canvasex01.html" target="_top">(<code class="filename">canvasex01.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex01.png" alt="A simple canvas graph to draw a text box (canvasex01.php)"></span> </div></div><p><br class="figure-break">
            </p>
            <p>The example in <a class="xref" href="ch17s03.html#fig.canvasex01" title="Figure 17.22. A simple canvas graph to draw a text box (canvasex01.php)">Figure 17.22. A simple canvas graph to draw a text box <code class="uri"><a class="uri" href="example_src/canvasex01.html" target="_top">(<code class="filename">canvasex01.php</code>)</a></code> </a> starts by creating a 400x200
                sized image. </p>
            <p>The margins are then set to to get a frame around the image. </p>
            <p>For canvases the margins has no effect in the way coordinates are entered. Top
                left is (0,0) and bottom right (including any potential margin and shadow) is the
                maximum. In this case the coordinate range are X:0-399, and Y:0-199</p>
            <p>The <code class="code">InitFrame()</code> method is then called which actually strokes the
                margin and plotarea to the graph. Since everything is stroked in the order the
                commands are given it is necessary to make sure that the graphical objects that
                should be on top are stroked last. This is different from the other graph types
                since they will hide these details and stroke the details in the graph in the
                correct order. </p>
            <p>We then create a Text object, setup it's properties, including the absolute screen
                position where we want the text, and then stroke it. </p>
            <p>The <code class="code">Text::Align()</code> method specifies the anchor point of the text as
                explained in <a class="xref" href="ch08.html" title="Chapter 8. Text and font handling">Chapter 8. <i>Text and font handling</i></a></p>
            <p>We also specify that the lines within the paragraph should be centered with a call
                to <code class="code">Text::ParagraphAlign()</code> Since we also choose to have a box around the
                text we have to make use of the method <code class="code">Text::SetBox()</code> which is used to
                specify the fill color, the border color and the shadow color (if the shadow color
                is set to '', no shadow will be used).</p>
            <p>Now we are ready to stroke the text onto the canvas. In order to do so we must
                specify the graphical context when stroking the text. The current graphic context is
                always available in the "<code class="code">$img</code>" property of the CanvasGraph
                class.</p>
            <p>This specification of the graphical context is needed to all Stroke method that is
                external to the main graph class.</p>
        </div>
        <div class="sect2" title="Adding lines and rectangles to a canvas"><div class="titlepage"><div><div><h3 class="title"><a name="id2578750"></a>Adding lines and rectangles to a canvas</h3></div></div></div>
            
            <p>A canvas also makes a good background for using standard graphic primitives, for
                example circles and lines. The first thing to remember is that this requires working
                with absolute screen coordinates and secondly that all drawing primitives are found
                in the Image Class accessible as a property of the Graph class. </p>
            <p>This means that to draw a line between absolute coordinates (0,0) and (100,100)
                the following code must be created</p>
            <p>
                </p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-code">$graph-&gt;img-&gt;Line(0, 0, 100, 100);</span></pre></td></tr></table></div><p>
            </p>
            <p>The following example shows how to create some basic graphic shapes on a
                canvas</p>
            <p>
                </p><div class="example"><a name="example.canvasex02"></a><p class="title"><b>Example 17.2. Drawing some basic geometric shapes on a canvas (<code class="filename">canvasex02.php</code>) </b></p><div class="example-contents">  <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content=&quot;text/plain; charset=utf-8&quot;</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex02.php,v 1.1 2002/08/27 20:08:57 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">teal</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a black line</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Line</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Circle</span><span class="hl-brackets">(</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a filled circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">red</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledCircle</span><span class="hl-brackets">(</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-number">100</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledRectangle</span><span class="hl-brackets">(</span><span class="hl-number">10</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-code">,</span><span class="hl-number">50</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a filled rounded rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledRoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-number">30</span><span class="hl-code">,</span><span class="hl-number">350</span><span class="hl-code">,</span><span class="hl-number">80</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. with a darker border</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">darkgreen</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">img</span><span class="hl-code">-&gt;</span><span class="hl-identifier">RoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">300</span><span class="hl-code">,</span><span class="hl-number">30</span><span class="hl-code">,</span><span class="hl-number">350</span><span class="hl-code">,</span><span class="hl-number">80</span><span class="hl-code">,</span><span class="hl-number">10</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-inlinetags">?&gt;</span></pre></td></tr></table></div></div></div><p><br class="example-break">  </p><div class="figure"><a name="fig.canvasex02"></a><p class="title"><b>Figure 17.23. Drawing some basic geometric shapes on a canvas <code class="uri"><a class="uri" href="example_src/canvasex02.html" target="_top">(<code class="filename">canvasex02.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex02.png" alt="Drawing some basic geometric shapes on a canvas (canvasex02.php)"></span> </div></div><p><br class="figure-break">
            </p>
        </div>
        <div class="sect2" title="Using a canvas scale together with the shape class"><div class="titlepage"><div><div><h3 class="title"><a name="id2578860"></a>Using a canvas scale together with the shape class</h3></div></div></div>
            
            <p>The previous method using absolute coordinates works. But it gives very little
                flexibility in, for example, scaling the image. Working with absolute coordinates is
                therefore not very practical and gets tedious for complex figures.</p>
            <p>To mitigate these issues the library offers a convenience class, <code class="code">class
                    CanvasScale</code>, this will allow the creation of a suitable scale that will
                make it easier to both create and scale the graph.</p>
            <p>In order to use a canvas scale the module
                    "<code class="filename">jpgraph_canvtools.php</code>" must first be included. In addition
                to the canvas scale class this module also provides the companion <code class="code">Shape</code>
                class. This companion shape class is used to draw shapes using the specified scale
                onto the canvas. </p>
            <p>Using the scale is quite simple and requires only two steps</p>
            <p>
                </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
                        <p>An instance of the scale class is first created with the CanvasGraph
                            instance as the first parameter</p>
                    </li><li class="listitem">
                        <p>The wanted scale is then specified with the wanted x and y
                            scales</p>
                    </li></ol></div><p>
            </p>
            <p>The following code snippet shows how this is done</p>
            <p>
                </p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code">
</span><span class="hl-var">$graph</span><span class="hl-code"> = </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">300</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> ... other canvas formatting</span><span class="hl-comment"></span><span class="hl-code">
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a new scale</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$scale</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasScale</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-var">$graph</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$scale</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-var">$xmin</span><span class="hl-code">, </span><span class="hl-var">$xmax</span><span class="hl-code">, </span><span class="hl-var">$ymin</span><span class="hl-code">, </span><span class="hl-var">$ymax</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> ...</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-inlinetags">?&gt;</span></pre></td></tr></table></div><p>
            </p>
            <p>The next step needed to be able to create geometric shapes is to create an
                instance of class Shape and give the canvas graph and the scale as the two
                parameters as the following line shows.</p>
            <p>
                </p><div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Shape</span><span class="hl-brackets">(</span><span class="hl-var">$graph</span><span class="hl-code">, </span><span class="hl-var">$scale</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-inlinetags">?&gt;</span></pre></td></tr></table></div><p>
            </p>
            <p>It is now possible to create arbitrary geometric shapes by using the provided
                methods in the shape class. The shape class provides the following methods</p>
            <p>
                </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
                        <p><code class="code">Shape::SetColor($aColor)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::Line($x1,$y1,$x2,$y2)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::Polygon($p,$aClosed=false)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::FilledPolygon($p)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::Bezier($p,$aSteps=40)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::Rectangle($x1,$y1,$x2,$y2)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::FilledRectangle($x1,$y1,$x2,$y2)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::Circle($x1,$y1,$r)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::FilledCircle($x1,$y1,$r)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::RoundedRectangle($x1,$y1,$x2,$y2,$r=null)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::FilledRoundedRectangle($x1,$y1,$x2,$y2,$r=null)</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::ShadowRectangle($x1,$y1,$x2,$y2,$fcolor=false,$shadow_width=null,$shadow_color=array(102,102,102))</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::SetTextAlign($halign,$valign="bottom")</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::StrokeText($x1,$y1,$txt,$dir=0,$paragraph_align="left")</code></p>
                    </li><li class="listitem">
                        <p><code class="code">Shape::
                                IndentedRectangle($xt,$yt,$w,$h,$iw=0,$ih=0,$aCorner=3,$aFillColor="",$r=4)</code></p>
                    </li></ul></div><p>
            </p>
            <p>We can now show a complete example of using the shape class</p>
            <p>
                </p><div class="example"><a name="example.canvasex03"></a><p class="title"><b>Example 17.3. Creating a canvas graph with a scale and using the shape class (<code class="filename">canvasex03.php</code>) </b></p><div class="example-contents">  <div class="hl-main"><table class="hl-table" width="100%"><tr><td class="hl-gutter" align="right" valign="top"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="hl-main" valign="top"><pre><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"> </span><span class="hl-comment">//</span><span class="hl-comment"> content=&quot;text/plain; charset=utf-8&quot;</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> </span><span class="hl-inlinedoc">$Id: canvasex03.php,v 1.1 2002/08/27 20:08:57 aditus Exp $</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvas.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-reserved">require_once</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">jpgraph/jpgraph_canvtools.php</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Define work space</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$xmax</span><span class="hl-code">=</span><span class="hl-number">20</span><span class="hl-code">;
</span><span class="hl-var">$ymax</span><span class="hl-code">=</span><span class="hl-number">20</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Setup a basic canvas we can work </span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasGraph</span><span class="hl-brackets">(</span><span class="hl-number">400</span><span class="hl-code">,</span><span class="hl-number">200</span><span class="hl-code">,</span><span class="hl-quotes">'</span><span class="hl-string">auto</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMargin</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-code">,</span><span class="hl-number">11</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetShadow</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetMarginColor</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">teal</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> We need to stroke the plotarea and margin before we add the</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> text since we otherwise would overwrite the text.</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">InitFrame</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Create a new scale</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$scale</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">CanvasScale</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$scale</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Set</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$xmax</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-var">$ymax</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> The shape class is wrapper around the Imgae class which translates</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-comment">//</span><span class="hl-comment"> the coordinates for us</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code"> = </span><span class="hl-reserved">new</span><span class="hl-code"> </span><span class="hl-identifier">Shape</span><span class="hl-brackets">(</span><span class="hl-var">$g</span><span class="hl-code">,</span><span class="hl-var">$scale</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
 
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Add a black line</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Line</span><span class="hl-brackets">(</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">20</span><span class="hl-code">,</span><span class="hl-number">20</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Circle</span><span class="hl-brackets">(</span><span class="hl-number">5</span><span class="hl-code">,</span><span class="hl-number">14</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. and a filled circle (x,y,diameter)</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">red</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledCircle</span><span class="hl-brackets">(</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledRectangle</span><span class="hl-brackets">(</span><span class="hl-number">15</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">19</span><span class="hl-code">,</span><span class="hl-number">14</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-comment">//</span><span class="hl-comment"> .. add a filled rounded rectangle</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">green</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">FilledRoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-comment">//</span><span class="hl-comment"> .. with a darker border</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">SetColor</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">darkgreen</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;
</span><span class="hl-var">$shape</span><span class="hl-code">-&gt;</span><span class="hl-identifier">RoundedRectangle</span><span class="hl-brackets">(</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">;
 
 
</span><span class="hl-comment">//</span><span class="hl-comment"> Stroke the graph</span><span class="hl-comment"></span><span class="hl-code">
</span><span class="hl-var">$g</span><span class="hl-code">-&gt;</span><span class="hl-identifier">Stroke</span><span class="hl-brackets">(</span><span class="hl-brackets">)</span><span class="hl-code">;
 
</span><span class="hl-inlinetags">?&gt;</span></pre></td></tr></table></div></div></div><p><br class="example-break">  </p><div class="figure"><a name="fig.canvasex03"></a><p class="title"><b>Figure 17.24. Creating a canvas graph with a scale and using the shape class <code class="uri"><a class="uri" href="example_src/canvasex03.html" target="_top">(<code class="filename">canvasex03.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex03.png" alt="Creating a canvas graph with a scale and using the shape class (canvasex03.php)"></span> </div></div><p><br class="figure-break">
            </p>
            <p>To show the usefulness of using the scale class <a class="xref" href="ch17s03.html#fig.canvasex04" title="Figure 17.25. Changing the image size to create a smaller version of the previous example (canvasex04.php)">Figure 17.25. Changing the image size to create a smaller version of the previous example <code class="uri"><a class="uri" href="example_src/canvasex04.html" target="_top">(<code class="filename">canvasex04.php</code>)</a></code> </a> shows the result after just changing the image size but keeping the code the
                same. The relation between the shapes will remain the same but in a smaller format
                to fit the new image size.</p>
            <p>
                </p><div class="figure"><a name="fig.canvasex04"></a><p class="title"><b>Figure 17.25. Changing the image size to create a smaller version of the previous example <code class="uri"><a class="uri" href="example_src/canvasex04.html" target="_top">(<code class="filename">canvasex04.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex04.png" alt="Changing the image size to create a smaller version of the previous example (canvasex04.php)"></span> </div></div><p><br class="figure-break">
            </p>
            <p>If we instead wanted to keep the image size but shrink the shapes we could just
                make the scale twice as large which would result in <a class="xref" href="ch17s03.html#fig.canvasex05" title="Figure 17.26. Keeping the image size but changing the scale (canvasex05.php)">Figure 17.26. Keeping the image size but changing the scale <code class="uri"><a class="uri" href="example_src/canvasex05.html" target="_top">(<code class="filename">canvasex05.php</code>)</a></code> </a></p>
            <p>
                </p><div class="figure"><a name="fig.canvasex05"></a><p class="title"><b>Figure 17.26. Keeping the image size but changing the scale <code class="uri"><a class="uri" href="example_src/canvasex05.html" target="_top">(<code class="filename">canvasex05.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex05.png" alt="Keeping the image size but changing the scale (canvasex05.php)"></span> </div></div><p><br class="figure-break">
            </p>
            <p>We previously mentioned that the Shape class was a wrapper around the image class
                with one exception. The exception is that it contains one additional method which
                draws an "indented rectangle". An indented rectangle is a rectangle where one of
                it's four corners have been moved into the rectangle <a class="xref" href="ch17s03.html#fig.canvasex06" title="Figure 17.27. Example of using an indented rectangle (canvasex06.php)">Figure 17.27. Example of using an indented rectangle <code class="uri"><a class="uri" href="example_src/canvasex06.html" target="_top">(<code class="filename">canvasex06.php</code>)</a></code> </a> shows an example of using this shape.</p>
            <p>
                </p><div class="figure"><a name="fig.canvasex06"></a><p class="title"><b>Figure 17.27. Example of using an indented rectangle <code class="uri"><a class="uri" href="example_src/canvasex06.html" target="_top">(<code class="filename">canvasex06.php</code>)</a></code> </b></p><div class="figure-contents">  <span class="inlinemediaobject"><img src="images/canvasex06.png" alt="Example of using an indented rectangle (canvasex06.php)"></span> </div></div><p><br class="figure-break">
            </p>
            <p>As a final note we mention the utility class <code class="code">class
                    CanvasRectangleText</code> This can be used to add a text with a rounded
                rectangle (possibly filled) onto the canvas. <a class="xref" href="ch08s02.html#fig.listfontsex1" title="Figure 8.1. List of all latin TTF fonts. (listfontsex1.php)">Figure 8.1. List of all latin TTF fonts. <code class="uri"><a class="uri" href="example_src/listfontsex1.html" target="_top">(<code class="filename">listfontsex1.php</code>)</a></code> </a>
                where all the available fonts were shown were using this class. </p>
        </div>
    </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"><a accesskey="u" href="ch17.html">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
